﻿
using BaseUtils.Helper;
using BaseUtils.Utils;
using Service.src.Flow.Server;
using Service.src.Model.Folw;
using Service.src.NW.Base;
using Service.src.NW.Enum;
using Service.src.NW.Model.Enum;
using Service.src.NW.Model.Folw;
using Service.src.NW.Model.Folw.Logic;
using System.Linq;

namespace Service.src.NW.Processor.Core
{
    public class LogicProcessor : BaseProcessor
    {
        static ScriptCompiler scriptCompiler = new ScriptCompiler();

        /// <summary>
        /// 逻辑运算
        /// </summary>
        /// <param name="Node"></param>
        /// <param name="input"></param>
        internal static void Run(NodeProcessor Node, NodeInputParam input)
        {
            NodeStatusEnum NODE_STATUS = NodeStatusEnum.SUCCESS;
            switch (Node.nodeType)
            {
                case NodeTypeEnum.LOGIC_SWITCH:
                    if (Node.NodeInputParam == null)
                    {
                        Node.Logger = new NodeLogger("参数输入错误");
                        Node.Code = (int)RuntimeErrorCodeEnum.NODE_INPUT_PARAM_NULL;
                        break;
                    }
                    bool _RES = true;
                    if (Node?.NodeInputParam?.NodeLogic?.Ranges.Any() == true)
                    {
                        foreach (RangeCondition item in Node?.NodeInputParam?.NodeLogic?.Ranges)
                        {
                            if (string.IsNullOrEmpty(item.Established))
                            {
                                Node.Logger = new NodeLogger("参数输入错误,未选择触发成立条件");
                                Node.Code = (int)RuntimeErrorCodeEnum.NODE_INPUT_PARAM_ESTABLISHED;
                                break;
                            }
                            if (item.TriggerNodeId == 0)
                            {
                                Node.Logger = new NodeLogger("参数输入错误,触发对象节点不能是默认值：0");
                                Node.Code = (int)RuntimeErrorCodeEnum.NODE_INPUT_PARAM_TRIGGER;
                                break;
                            }

                            dynamic v = GetNodeInputParamValue(Node, item);
                            bool es = false;
                            if (v != null)
                            {
                                bool IsNumber = CommonUtil.IsNumber(v + "");
                                if (!(v is int) && IsNumber)
                                {
                                    v = int.Parse(v + "");
                                }
                                if (v is int)
                                {
                                    if (item.Established == "OK" && item.Min <= v && item.Max >= v)
                                    {
                                        es = true;
                                    }
                                    if (item.Established == "NG" && !(item.Min <= v && item.Max >= v))
                                    {
                                        es = true;
                                    }
                                }
                            }
                            if (es)
                            {
                                _RES = false;
                                SendNodeLoggerWarning(Node, $"触发节点：{item.TriggerNodeId} = {es}，", Node.Code.ToString().ToEnum<RuntimeErrorCodeEnum>());
                            }
                            else
                            {
                                SendNodeLoggerWarning(Node, $"触发源：{item.ParamName},触发值{v}，");
                            }
                            item.IsTrigger = es;
                        }
                    }

                    SetNodeOutParamValue(Node, NodeOutParamNameEnum.NODE_STATUS, NodeStatusEnum.SUCCESS);
                    if (_RES)
                    {
                        Node.NodeStatus = 0;
                        SendNodeLoggerWarning(Node, $"未触发任何分支：", RuntimeErrorCodeEnum.DEFAULT);
                    }
                    break;
                case NodeTypeEnum.LOGIC_USER_SCRIPT:
                    scriptCompiler.RunScript(Node);
                    SetNodeOutParamValue(Node, NodeOutParamNameEnum.NODE_STATUS, Node.NodeStatus);
                    break;
                case NodeTypeEnum.LOGIC_TRIGGER_FLOW:
                    TriggerFlow flow = Node?.NodeInputParam?.NodeLogic?.Flow;
                    if (flow == null)
                    {
                        NODE_STATUS = NodeStatusEnum.ERROR;
                        SendNodeLoggerError(Node, $"节点配置错误，请检查节点配置，节点id={Node.id}", RuntimeErrorCodeEnum.NODE_INPUT_PARAM_NULL);
                    }
                    int FlowId = flow?.InputParam?.DataSourceId ?? 0;
                    int OperationType = flow?.OperationType ?? -1;

                    if (FlowId <= 0)
                    {
                        NODE_STATUS = NodeStatusEnum.ERROR;
                        SendNodeLoggerError(Node, $"流程ID错误，请检测流程，节点id={Node.id}");
                    }
                    SetNodeOutParamValue(Node, NodeOutParamNameEnum.NODE_STATUS, NODE_STATUS);
                    Complete(Node, NODE_STATUS);

                    if (NODE_STATUS == NodeStatusEnum.SUCCESS && flow.OperationType == 1)
                    {
                        FlowServer.RunFlow(FlowId);
                        SendNodeLoggerInfo(Node, $"已触发流程：流程ID = {FlowId}");
                    }
                    if (NODE_STATUS == NodeStatusEnum.SUCCESS && flow.OperationType == 0)
                    {
                        FlowServer.StopFlow(FlowId);
                        SendNodeLoggerInfo(Node, $"已停止流程：流程ID = {FlowId}");
                    }
                    break;
                case NodeTypeEnum.LOGIC_CALCULATOR:
                    CalculatorProcessor.Run(Node, input);
                    Complete(Node, Node.NodeStatus);
                    break;
            }
        }
    }
}
